11586
4208
Come mai certe stringhe casuali producono colori quando vengono immesse come colori di sfondo in HTML? Per esempio:
 prova 
... produce un documento con uno sfondo rosso su tutti i browser e piattaforme.
È interessante notare che, mentre chucknorri produce anche uno sfondo rosso, chucknorr produce uno sfondo giallo.
Cosa sta succedendo qui? 
È un residuo dei giorni di Netscape:
Le cifre mancanti vengono trattate come 0 [...]. Una cifra errata viene semplicemente interpretata come 0. Ad esempio i valori # F0F0F0, F0F0F0, F0F0F, #FxFxFx e FxFxFx sono tutti uguali.
È tratto dal post del blog Un piccolo sproloquio sull'analisi del colore di Microsoft Internet Explorer che lo copre in grande dettaglio, comprese le lunghezze variabili dei valori di colore, ecc
Se applichiamo le regole a turno dal post del blog, otteniamo quanto segue:
Sostituisci tutti i caratteri esadecimali non validi con 0:
chucknorris diventa c00c0000000
Completa fino al numero totale successivo di caratteri divisibile per 3 (11 → 12):
c00c 0000 0000
Dividi in tre gruppi uguali, con ogni componente che rappresenta il componente di colore corrispondente di un colore RGB:
RGB (c00c, 0000, 0000)
Tronca ciascuno degli argomenti da destra in basso a due caratteri.
Che, infine, dà il seguente risultato:
RGB (c0, 00, 00) = # C00000 o RGB (192, 0, 0)
Ecco un esempio che mostra l'attributo bgcolor in azione, per produrre questo campione di colore "straordinario":
chuck norris Mr T ninjaturtle
sick crap grass
Questo risponde anche all'altra parte della domanda: Perché bgcolor = "chucknorr" produce un colore giallo? Ebbene, se applichiamo le regole, la stringa è: c00c00000 => c00 c00 000 => c0 c0 00 [RGB (192, 192, 0)] Che dà un colore giallo oro chiaro. Poiché la stringa inizia con 9 caratteri, questa volta manterremo la seconda "C", quindi finisce nel valore del colore finale. Inizialmente ho riscontrato questo quando qualcuno ha sottolineato che potresti fare color = "crap" e, beh, esce marrone. | Mi dispiace non essere d'accordo, ma secondo le regole per l'analisi di un valore di colore legacy pubblicate da @Yuhong Bao, chucknorris NON equivale a # CC0000, ma piuttosto a # C00000, una tonalità di rosso molto simile ma leggermente diversa. Ho usato l'add-on Firefox ColorZilla per verificarlo. Le regole affermano: rendi la stringa una lunghezza multipla di 3 aggiungendo 0: chucknorris0 separare la corda in 3 corde di uguale lunghezza: chuc knor ris0 troncare ogni stringa a 2 caratteri: ch kn ri mantieni i valori esadecimali e aggiungi 0 dove necessario: C0 00 00 Sono stato in grado di utilizzare queste regole per interpretare correttamente le seguenti stringhe: Portafortuna Fortuna LuckBeALady LuckBeALadyTonight Stile Gangnam AGGIORNAMENTO: I rispondenti originali che hanno detto che il colore era # CC0000 da allora hanno modificato le loro risposte per includere la correzione. | La maggior parte dei browser ignorerà semplicemente i valori NON esadecimali nella stringa del colore, sostituendo le cifre non esadecimali con zeri. ChuCknorris si traduce in c00c0000000. A questo punto, il browser dividerà la stringa in tre sezioni uguali, indicando i valori di Rosso, Verde e Blu: c00c 0000 0000. I bit extra in ogni sezione verranno ignorati, il che rende il risultato finale # c00000 che è un colore rossastro. Nota, questo non si applica all'analisi del colore CSS, che segue lo standard CSS.

Rossastro

Come sopra

Nero

| Il motivo è che il browser non riesce a capirlo e cerca di tradurlo in qualche modo in ciò che può capire e in questo caso in un valore esadecimale! ... chucknorris inizia con c che è un carattere riconosciuto in esadecimale, inoltre converte tutti i caratteri non riconosciuti in 0! Quindi chucknorris in formato esadecimale diventa: c00c00000000, tutti gli altri caratteri diventano 0 ec rimane dove sono ... Ora vengono divisi per 3 per RGB (rosso, verde, blu) ... R: c00c, G: 0000, B: 0000 ... Ma sappiamo che un esadecimale valido per RGB è di soli 2 caratteri, significa R: c0, G: 00, B: 00 Quindi il vero risultato è: bgcolor = "# c00000"; Ho anche aggiunto i passaggi nell'immagine come riferimento rapido per te: | Il browser sta tentando di convertire chucknorris in un codice colore esadecimale, perché non è un valore valido. In chucknorris, tutto tranne c non è un valore esadecimale valido. Quindi viene convertito in c00c00000000. Che diventa # c00000, una sfumatura di rosso. Questo sembra essere un problema principalmente con Internet Explorer e Opera (12) poiché sia ​​Chrome (31) che Firefox (26) lo ignorano. P.S. I numeri tra parentesi sono le versioni del browser su cui ho provato. Su una nota più leggera Chuck Norris non è conforme agli standard web. Gli standard web sono conformi a lui. # BADA55 | La specifica HTML WHATWG ha l'algoritmo esatto per analizzare un colore legacyvalore: https://html.spec.whatwg.org/multipage/infrastructure.html#rules-for-parsing-a-legacy-colour-value. Il codice Netscape Classic utilizzato per analizzare le stringhe di colore è open source: https://dxr.mozilla.org/classic/source/lib/layout/layimage.c#155. Ad esempio, si noti che ogni carattere viene analizzato come una cifra esadecimale e quindi viene spostato in un numero intero a 32 bit senza verificare l'overflow. Solo otto cifre esadecimali rientrano in un numero intero a 32 bit, motivo per cui vengono considerati solo gli ultimi 8 caratteri. Dopo aver analizzato le cifre esadecimali in interi a 32 bit, vengono quindi troncate in interi a 8 bit dividendole per 16 fino a quando non si adattano a 8 bit, motivo per cui gli zeri iniziali vengono ignorati. Aggiornamento: questo codice non corrisponde esattamente a quanto definito nelle specifiche, ma l'unica differenza è costituita da poche righe di codice. Penso che siano state aggiunte queste righe (in Netscape 4): if (bytes_per_val> 4) { bytes_per_val = 4; } | Risposta: Il browser proverà a convertire chucknorris in un valore esadecimale. Poiché c è l'unico carattere esadecimale valido in chucknorris, il valore si trasforma in: c00c00000000 (0 per tutti i valori non validi). Il browser quindi divide il risultato in 3 gruppi: rosso = c00c, verde = 0000, blu = 0000. Poiché i valori esadecimali validi per gli sfondi HTML contengono solo 2 cifre per ogni tipo di colore (r, g, b), le ultime 2 cifre vengono troncate da ciascun gruppo, lasciando un valore rgb di c00000 che è un colore dai toni rossastri. | chucknorris inizia con c e il browser lo legge in un valore esadecimale. Perché A, B, C, D, E e F sono caratteri esadecimali. Il browser converte chucknorris in un valore esadecimale, C00C00000000. Quindi il valore esadecimale C00C00000000 viene convertito nel formato RGB (diviso per 3): C00C00000000 ⇒ R: C00C, G: 0000, B: 0000 Il browser necessita solo di due cifre per indicare il colore: R: C00C, G: 0000, B: 0000 ⇒ R: C0, G: 00, B: 00 ⇒ C00000 Infine, mostra bgcolor = C00000 nel browser web. Ecco un esempio che lo dimostra:
chucknorris c00c00000000 c00000
| Le regole per l'analisi dei colori sugli attributi legacy comportano passaggi aggiuntivi rispetto a quelli menzionati nelle risposte esistenti. Il componente troncato a 2 cifre è descritto come: Elimina tutti i caratteri tranne gli ultimi 8 Scartare gli zeri iniziali uno per uno finché tutti i componenti hanno uno zero iniziale Elimina tutti i caratteri tranne i primi 2 Qualche esempio: oooFoooFoooF 000F 000F 000F <- sostituire, tampone e pezzo 0F 0F 0F <- zeri iniziali troncati 0F 0F 0F <- troncato a 2 caratteri da destra oooFooFFoFFF 000F 00FF 0FFF <- sostituisci, riempi e blocchi 00F 0FF FFF <- zeri iniziali troncati 00 0F FF <- troncato a 2 caratteri da destra ABCooooooABCooooooABCoooooo ABC000000 ABC000000 ABC000000 <- sostituisci, riempi e blocchi BC000000 BC000000 BC000000 <- troncato a 8 caratteri da sinistra BC BC BC <- troncato a 2 caratteri da destra AoCooooooAoCooooooAoCoooooo A0C000000 A0C000000 A0C000000 <- sostituire, riempire e bloccare 0C000000 0C000000 0C000000 <- troncato a 8 caratteri da sinistra C000000 C000000 C000000 <- zeri iniziali troncati C0 C0 C0 <- troncato a 2 caratteri da destra Di seguito è un'implementazione parziale dell'algoritmo. Non gestisce errori o casi in cui l'utente inserisce un colore valido. function parseColor (input) { // todo: restituisce l'errore se l'input è "" input = input.trim (); // todo: restituisce l'errore se l'input è "trasparente" // todo: restituisce il corrispondente #rrggbb se l'input è un colore con nome // todo: return #rrggbb se l'input corrisponde a #rgb // todo: sostituisci i punti del codice Unicode maggiori di U + FFFF con 00 if (input.length> 128) { input = input.slice (0, 128); } if (input.charAt (0) === "#") { input = input.slice (1); } input = input.replace (/ [^ 0-9A-Fa-f] / g, "0"); while (input.length === 0 || input.length% 3> 0) { input + = "0"; } var r = input.slice (0, input.length / 3); var g = input.slice (input.length / 3, input.length * 2/3); var b = input.slice (input.length * 2/3); if (r.length> 8) { r = r.slice (-8); g = g. fetta (-8); b = b. fetta (-8); } while (r.length> 2 && r.charAt (0) === "0" && g.charAt (0) === "0" && b.charAt (0) === "0") { r = r.slice (1); g = g. fetta (1); b = b. fetta (1); } if (r.length> 2) { r = r.slice (0, 2); g = g. fetta (0, 2); b = b. fetta (0, 2); } return "#" + r.padStart (2, "0") + g.padStart (2, "0") + b.padStart (2, "0"); } $ (function () { $ ("# input"). on ("change", function () { var input = $ (questo) .val (); var color = parseColor (input); var $ celle = $ ("# risultato tbody td"); $ cells.eq (0) .attr ("bgcolor", input); $ cells.eq (1) .attr ("bgcolor", color); varvalore: https://html.spec.whatwg.org/multipage/infrastructure.html#rules-for-parsing-a-legacy-colour-value. Il codice Netscape Classic utilizzato per analizzare le stringhe di colore è open source: https://dxr.mozilla.org/classic/source/lib/layout/layimage.c#155. Ad esempio, si noti che ogni carattere viene analizzato come una cifra esadecimale e quindi viene spostato in un numero intero a 32 bit senza verificare l'overflow. Solo otto cifre esadecimali rientrano in un numero intero a 32 bit, motivo per cui vengono considerati solo gli ultimi 8 caratteri. Dopo aver analizzato le cifre esadecimali in interi a 32 bit, vengono quindi troncate in interi a 8 bit dividendole per 16 fino a quando non si adattano a 8 bit, motivo per cui gli zeri iniziali vengono ignorati. Aggiornamento: questo codice non corrisponde esattamente a quanto definito nelle specifiche, ma l'unica differenza è costituita da poche righe di codice. Penso che siano state aggiunte queste righe (in Netscape 4): if (bytes_per_val> 4) { bytes_per_val = 4; } | Risposta: Il browser proverà a convertire chucknorris in un valore esadecimale. Poiché c è l'unico carattere esadecimale valido in chucknorris, il valore si trasforma in: c00c00000000 (0 per tutti i valori non validi). Il browser quindi divide il risultato in 3 gruppi: rosso = c00c, verde = 0000, blu = 0000. Poiché i valori esadecimali validi per gli sfondi HTML contengono solo 2 cifre per ogni tipo di colore (r, g, b), le ultime 2 cifre vengono troncate da ciascun gruppo, lasciando un valore rgb di c00000 che è un colore dai toni rossastri. | chucknorris inizia con c e il browser lo legge in un valore esadecimale. Perché A, B, C, D, E e F sono caratteri esadecimali. Il browser converte chucknorris in un valore esadecimale, C00C00000000. Quindi il valore esadecimale C00C00000000 viene convertito nel formato RGB (diviso per 3): C00C00000000 ⇒ R: C00C, G: 0000, B: 0000 Il browser necessita solo di due cifre per indicare il colore: R: C00C, G: 0000, B: 0000 ⇒ R: C0, G: 00, B: 00 ⇒ C00000 Infine, mostra bgcolor = C00000 nel browser web. Ecco un esempio che lo dimostra:
chucknorris c00c00000000 c00000
| Le regole per l'analisi dei colori sugli attributi legacy comportano passaggi aggiuntivi rispetto a quelli menzionati nelle risposte esistenti. Il componente troncato a 2 cifre è descritto come: Elimina tutti i caratteri tranne gli ultimi 8 Scartare gli zeri iniziali uno per uno finché tutti i componenti hanno uno zero iniziale Elimina tutti i caratteri tranne i primi 2 Qualche esempio: oooFoooFoooF 000F 000F 000F <- sostituire, tampone e pezzo 0F 0F 0F <- zeri iniziali troncati 0F 0F 0F <- troncato a 2 caratteri da destra oooFooFFoFFF 000F 00FF 0FFF <- sostituisci, riempi e blocchi 00F 0FF FFF <- zeri iniziali troncati 00 0F FF <- troncato a 2 caratteri da destra ABCooooooABCooooooABCoooooo ABC000000 ABC000000 ABC000000 <- sostituisci, riempi e blocchi BC000000 BC000000 BC000000 <- troncato a 8 caratteri da sinistra BC BC BC <- troncato a 2 caratteri da destra AoCooooooAoCooooooAoCoooooo A0C000000 A0C000000 A0C000000 <- sostituire, riempire e bloccare 0C000000 0C000000 0C000000 <- troncato a 8 caratteri da sinistra C000000 C000000 C000000 <- zeri iniziali troncati C0 C0 C0 <- troncato a 2 caratteri da destra Di seguito è un'implementazione parziale dell'algoritmo. Non gestisce errori o casi in cui l'utente inserisce un colore valido. function parseColor (input) { // todo: restituisce l'errore se l'input è "" input = input.trim (); // todo: restituisce l'errore se l'input è "trasparente" // todo: restituisce il corrispondente #rrggbb se l'input è un colore con nome // todo: return #rrggbb se l'input corrisponde a #rgb // todo: sostituisci i punti del codice Unicode maggiori di U + FFFF con 00 if (input.length> 128) { input = input.slice (0, 128); } if (input.charAt (0) === "#") { input = input.slice (1); } input = input.replace (/ [^ 0-9A-Fa-f] / g, "0"); while (input.length === 0 || input.length% 3> 0) { input + = "0"; } var r = input.slice (0, input.length / 3); var g = input.slice (input.length / 3, input.length * 2/3); var b = input.slice (input.length * 2/3); if (r.length> 8) { r = r.slice (-8); g = g. fetta (-8); b = b. fetta (-8); } while (r.length> 2 && r.charAt (0) === "0" && g.charAt (0) === "0" && b.charAt (0) === "0") { r = r.slice (1); g = g. fetta (1); b = b. fetta (1); } if (r.length> 2) { r = r.slice (0, 2); g = g. fetta (0, 2); b = b. fetta (0, 2); } return "#" + r.padStart (2, "0") + g.padStart (2, "0") + b.padStart (2, "0"); } $ (function () { $ ("# input"). on ("change", function () { var input = $ (questo) .val (); var color = parseColor (input); var $ celle = $ ("# risultato tbody td"); $ cells.eq (0) .attr ("bgcolor", input); $ cells.eq (1) .attr ("bgcolor", color); var